﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Collections;

namespace XSerialization.Tests
{
    public class XmlAssert
    {
        XElement element;
 
        public XmlAssert(string xml)
        {
            element = XElement.Parse(xml);
            check = () => { };
        }

        Action check;
        public XmlAssert(XElement el, Action check)
        {
            this.element = el;
            this.check = check;
        }

        public XmlAssert El(string name, object value)
        {
            return new XmlAssert(element,
                () => { check(); Assert.AreEqual(value.ToString(), element.Element(name).Value); }
                    );
        }

        public XmlAssert ListSub(string name, int pos)
        {
            return new XmlAssert(element.Elements(name).Skip(pos).First(), check);
        }

        public XmlAssert Value(object value)
        {
            return new XmlAssert(element,
                () => { check(); Assert.AreEqual(value.ToString(), element.Value); }
                    );
        }

        public XmlAssert List<T>(string name, string itemName, IEnumerable<T> collection, Func<XmlAssert, T, XmlAssert> f)
        {
            var result = Sub(name);
            int count = 0;
            foreach (var o in collection)
            {
                result = result.ListSub(itemName, count);
                result = f(result, o);
                result = result.EndSub();
                count++;
            }
            result = result.EndSub();
            return result;
        }

        public XmlAssert Sub(string name)
        {
            return new XmlAssert(element.Element(name), check);
        }

        public XmlAssert EndSub()
        {
            return new XmlAssert(element.Parent, check);
        }

        public void Check()
        {
            check();
        }
        public static XmlAssert Create(string xml)
        {
            return new XmlAssert(xml);
        }
    }
}
